const {src, dest, parallel,series,watch} = require('gulp');
const del = require('del');
const browerSync = require('browser-sync');
const loadPlugins = require('gulp-load-plugins');
const plugins = loadPlugins();
const bs = browerSync.create();
// cwd返回当前命令行所在的工作目录
const cwd = process.cwd() 
// 默认配置
let config = {
    data: {
        menus: [
          {
            name: 'Home',
            icon: 'aperture',
            link: 'index.html',
          },

          {
            name: 'About',
            link: 'about.html',
          },
          {
            name: 'Contact',
            link: '#',
            children: [
              {
                name: 'Twitter',
                link: 'https://twitter.com/w_zce',
              },
              {
                name: 'About',
                link: 'https://weibo.com/zceme',
              },
              {
                name: 'divider',
              },
              {
                name: 'About',
                link: 'https://github.com/zce',
              },
            ],
          },
        ],
        pkg: require('./package.json'),
        date: new Date(),
      },
    // default config
    build: {
      src:'src',
      dist:'dist',
      temp: '.tmp',
      public: 'public',
      paths: {
        styles: 'assets/styles/*.scss',
        scripts:'assets/scripts/*.js',
        pages:'*.html',
        images:'assets/images/**',
        fonts:'assets/fonts/**',
      }
    }
}

// 脚本
const script = () => {
  return src(config.build.paths.scripts, {base: config.build.src,cwd: config.build.src})
    // 当前找不到，给上找
    .pipe(plugins.babel({presets: [require('@babel/preset-env')] }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({stream: true}))
};

// 样式处理
const style = () => {

  return (
    src(config.build.paths.styles, {base: config.build.src,cwd: config.build.src})
      .pipe(plugins.sass({outputStyle: 'expanded'}))
      .pipe(dest(config.build.temp))
      .pipe(bs.reload({stream: true}))
  );
};


// 处理页面
const page = () => {
  return src(config.build.paths.pages, {base: config.build.src,cwd: config.build.src})
    .pipe(plugins.swig({data:config.data,defaults: {cache: false}}))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({stream: true}))

};

const image = () => {
  return src(config.build.paths.images, {base: config.build.src, cwd: config.build.src})
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
};

// 处理字体
const font = () => {
  return src(config.build.paths.fonts,{base: config.build.src,cwd: config.build.src})
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist));
};
// 其他文件
const extra = () => {
  return src('**', {base: config.build.public,cwd: config.build.public})
    .pipe(dest(config.build.dist))
}

// 清除
const clean = () => {
  // 返回promise对象
  return del([config.build.dist,config.build.temp])
}
// 使用引用
const useref = () => {
  return src(config.build.paths.pages,{base: config.build.temp,cwd: config.build.temp})
  // return src('.tmp/*.html', {base: '.tmp', cwd: '.'})
    .pipe(plugins.useref({searchPath: [config.build.temp, '.', '..']}))
    // html, css,js都需要压缩
    /* 
     html: gulp-htmlmin 
     js: gulp - uglify
     css: gulp-clean-css 
     gulp-if 需要判断读取流中是什么格式都文件，
    */
   .pipe(plugins.if(/\.js$/, plugins.uglify()))
   .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
  //  配置压缩选项，默认只压缩空格，不压缩换行
  // collapseWhitespace: true
   .pipe(plugins.if(/\.html$/, plugins.htmlmin({
    collapseWhitespace: true,
    minifyCSS:true,
    minifyJS:true // minify Javascript in Script
   })))
   .pipe(dest(config.build.dist))
}
// 组合运行,任务之间没有关联，直接进行并行构建
const compile = parallel(style, script, page);
// 先clean，后构建,上线之前构建项目
const build = series(
  clean,
  parallel(
    series(
      compile,
      useref
    ), 
    extra, 
    image, 
    font
    )
  );
// 使用插件导入所有插件，gulp-load-plugins
const develop = () => {
  // watch 第一个监听路径，第二个执行的任务
  // 图片字体文件，在dev阶段不需要压缩，以免降低构建效率
  watch(config.build.paths.pages, {cwd: config.build.src}, page);
  watch(config.build.paths.scripts, {cwd: config.build.src}, script);
  watch(config.build.paths.styles, {cwd: config.build.src}, style);

  // 其他资源统一处理,这些样式改变，重新发起请求，编译更新
  watch([config.build.paths.fonts, config.build.paths.images,
  ], {cwd: config.build.src},bs.reload)
  watch(['**'],{cwd: config.build.public}, bs.reload)
  bs.init({
    notify: false,
    port:2080,
    open: true, // 是否自动打开浏览器;
    // files:'dist/**',
    server: {
      // 先找dist找不到找src，然后public，在开发阶段，构建图片和字体文件没有实际意义
      // 所以直接引用 src里面的资源
      baseDir: [config.build.temp, config.build.dist, config.build.public],
      routes: {
        '/node_modules':'node_modules',
      }
    }
  })
}

// 监听之前，先构建一次dist,编译完成，在开启服务器，打开浏览器
const serve = series(compile,develop)
// 监听src下文件变化，然后进行构建，最后同步；
// 导出
module.exports = {
  clean,
  build,
  serve,
};
